import com.fasterxml.jackson.databind.ObjectMapper;
import model.User;
import model.UserDao;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf8");
        // 1. 从请求中, 获取到用户名和密码.
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if (username == null || username.equals("") || password == null || password.equals("")) {
            // 用户名密码残缺, 登录必然失败!!
            String html = "<h3>登录失败! 缺少用户名或者密码! </h3>";
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        // 2. 读取数据库, 看看这里的用户名密码, 是否和数据库中的匹配.
        UserDao userDao = new UserDao();
        User user = userDao.selectUserByName(username);
        if (user == null) {
            // 用户名不存在
            String html = "<h3>用户名或密码错误! </h3>";
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        if (!password.equals(user.getPassword())) {
            // 密码错误
            String html = "<h3>用户名或密码错误! </h3>";
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        // 3. 用户名和密码都正确, 登录成功!! 需要设置会话!!
        //    此处需要先创建出一个会话.
        HttpSession session = req.getSession(true);
        // 此处就把用户对象存储到 session 中了. 下次用户访问其他页面, 就可以直接拿到会话, 进一步拿到之前的 user 对象了.
        session.setAttribute("user", user);
        // 4. 返回一个重定向响应, 能够跳转到博客列表页.
        resp.sendRedirect("blog_list.html");
    }

    // 通过这个方法, 判定用户的登录状态. 已登录, 返回 200. 未登录返回 403
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 看当前请求是否已经存在会话. 并且当前的会话是否包含 user 对象.
        HttpSession session = req.getSession(false);
        if (session == null) {
            // 会话不存在, 未登录状态.
            resp.setStatus(403);
            return;
        }
        User user = (User) session.getAttribute("user");
        if (user == null) {
            // 虽然会话对象存在, 但是用户对象没有, 未登录状态.
            resp.setStatus(403);
            return;
        }
        // 已经登录了!
        // 200 是默认的状态码, 此处不写 200 也是可以的.
        resp.setStatus(200);
        resp.setContentType("application/json;charset=utf8");
        user.setPassword(""); // 避免把密码也返回给前端. 提高密码泄露的风险.
        String respJson = objectMapper.writeValueAsString(user);
        resp.getWriter().write(respJson);
    }
}
 import com.fasterxml.jackson.databind.ObjectMapper;
         import model.Blog;
         import model.BlogDao;
         import model.User;
         import model.UserDao;

         import javax.servlet.ServletException;
         import javax.servlet.annotation.WebServlet;
         import javax.servlet.http.HttpServlet;
         import javax.servlet.http.HttpServletRequest;
         import javax.servlet.http.HttpServletResponse;
         import java.io.IOException;

@WebServlet("/user")
public class UserServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 先读取出 blogId
        String blogId = req.getParameter("blogId");
        if (blogId == null || blogId.equals("")) {
            // 直接返回一个 userId 为 0 的对象. 因为最终返回的是一个 json 数据.
            // 此处也是返回 json 格式比较好, 如果返回一个 html, 前端处理就要麻烦.
            String respJson = objectMapper.writeValueAsString(new User());
            resp.setContentType("application/json; charset=utf8");
            resp.getWriter().write(respJson);
            System.out.println("参数给定的 blogId 为空!");
            return;
        }
        // 2. 查询数据库, 查询对应的 Blog 对象
        BlogDao blogDao = new BlogDao();
        Blog blog = blogDao.selectOne(Integer.parseInt(blogId));
        if (blog == null) {
            String respJson = objectMapper.writeValueAsString(new User());
            resp.setContentType("application/json; charset=utf8");
            resp.getWriter().write(respJson);
            System.out.println("参数给定的 blogId 不存在!");
            return;
        }
        // 3. 根据 blog 中的 userId, 查询作者信息.
        UserDao userDao = new UserDao();
        User user = userDao.selectUserById(blog.getUserId());
        if (user == null) {
            String respJson = objectMapper.writeValueAsString(new User());
            resp.setContentType("application/json; charset=utf8");
            resp.getWriter().write(respJson);
            System.out.println("该博客对应的作者不存在!");
            return;
        }
        // 4. 把 user 对象返回给页面了.
        String respJson = objectMapper.writeValueAsString(user);
        resp.setContentType("application/json; charset=utf8");
        resp.getWriter().write(respJson);
    }
}

package api;

        import javax.servlet.ServletException;
        import javax.servlet.annotation.WebServlet;
        import javax.servlet.http.HttpServlet;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        import javax.servlet.http.HttpSession;
        import java.io.IOException;

@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession(false);
        if (session == null) {
            // 用户本来就没登录. 谈不上注销. 不过此处也没必要报错~~ 直接跳转到登录页即可.
            resp.sendRedirect("login.html");
            return;
        }
        // user 存在, 就删除了. 不存在, 也不会有副作用.
        session.removeAttribute("user");
        resp.sendRedirect("login.html");
    }
}

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf8");
        // 1. 先从请求中拿到 标题 和 正文.
        String title = req.getParameter("title");
        String content = req.getParameter("content");
        if (title == null || title.equals("") || content == null || content.equals("")) {
            String html = "<h3>title 或者 content 为空! 新增博客失败!</h3>";
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        // 2. 从会话中拿到作者的 id
        HttpSession session = req.getSession(false);
        if (session == null) {
            String html = "<h3>当前用户未登录! 新增博客失败!</h3>";
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        User user = (User) session.getAttribute("user");
        if (user == null) {
            String html = "<h3>当前用户未登录! 新增博客失败!</h3>";
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        // 3. 构造 Blog 对象.
        Blog blog = new Blog();
        blog.setUserId(user.getUserId());
        blog.setTitle(title);
        blog.setContent(content);
        blog.setPostTime(new Timestamp(System.currentTimeMillis()));
        // 4. 插入 blog 对象到数据库中
        BlogDao blogDao = new BlogDao();
        blogDao.insert(blog);
        // 5. 跳转到博客列表页
        resp.sendRedirect("blog_list.html");
    }
}

// 把一个 Blog 对象插入到数据库中.
public void insert(Blog blog) {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
        // 1. 建立连接
        connection = DBUtil.getConnection();
        // 2. 构造 sql
        String sql = "insert into blog values(null, ?, ?, ?, ?)";
        statement = connection.prepareStatement(sql);
        statement.setString(1, blog.getTitle());
        statement.setString(2, blog.getContent());
        statement.setInt(3, blog.getUserId());
        // 如果数据库表里面是 datetime 类型, 插入数据的时候, 按照 TimeStamp 来插入或者按照格式化时间来插入都是可以的.
        statement.setString(4, blog.getPostTime());
        // 3. 执行 SQL
        statement.executeUpdate();
        } catch (SQLException e) {
        e.printStackTrace();
        } finally {
        DBUtil.close(connection, statement, null);
        }
        }



